基于Java实现图片滑动验证(包含前端代码)

您所在的位置:网站首页 java 图片验证码识别 基于Java实现图片滑动验证(包含前端代码)

基于Java实现图片滑动验证(包含前端代码)

2024-01-02 15:09| 来源: 网络整理| 查看: 265

前言

1、下面是一个效果展示;

2、先抱怨一下,在博客上面的抄袭真的非常严重,为了实现一个图片滑动验证,我搜索了挺久的资料,不过内容翻来覆去就是同样的内容,千篇一律,作者还各不相同;内容相同我就不多说了,毕竟能解决问题就行,然而恰恰相反,这些东西都没有为我实质性地解决问题。可能图片验证是一个需要前后台同时交互的功能吧,从业的人员大部分都是偏向后台或者偏向前台的,所以写出来的博客都不能完整阐述整个流程,下面是我自己实践完成的内容,记录一下,供各位参阅斧正。

注:由于使用到的控件和工具较多,有许多地方做了省略,这里只做核心流程的记录。

一、后端图片裁剪与生成

    首先是一个图片处理工具VerifyImageUtil.class,它主要的作用是生成两张图片:一张被扣除了一部分的原始图片;一张抠出来图片。两两结合,可以组成一张完整的图片。原始图片(target目录)提供了20张,规格都是590*360的;抠图需要的模板图(template目录)有4张,规格都是93*360的(图片等各种资源会在文末给出)。将图片资源导入到我们项目的静态资源路径下(你也可以通过其他方式存储它们),我这边是Spring Boot的项目,所以就放在resource下的static目录下了:

下面是 VerifyImageUtil.class

package com.mine.risk.util; import org.apache.commons.lang.StringUtils; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.text.NumberFormat; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Random; /** * 滑块验证工具类 * @author : spirit * @date : Created in 10:57 2019/9/05 */ public class VerifyImageUtil { /** 源文件宽度 */ private static final int ORI_WIDTH = 590; /** 源文件高度 */ private static final int ORI_HEIGHT = 360; /** 抠图坐标x */ private static int X; /** 抠图坐标y */ private static int Y; /** 模板图宽度 */ private static int WIDTH; /** 模板图高度 */ private static int HEIGHT; public static int getX() { return X; } public static int getY() { return Y; } /** * 根据模板切图 * @param templateFile 模板文件 * @param targetFile 目标文件 * @param templateType 模板文件类型 * @param targetType 目标文件类型 * @return 切图map集合 * @throws Exception 异常 */ public static Map pictureTemplatesCut(File templateFile, File targetFile, String templateType, String targetType) throws Exception { Map pictureMap = new HashMap(2); if (StringUtils.isEmpty(templateType) || StringUtils.isEmpty(targetType)) { throw new RuntimeException("file type is empty"); } InputStream targetIs = new FileInputStream(targetFile); // 模板图 BufferedImage imageTemplate = ImageIO.read(templateFile); WIDTH = imageTemplate.getWidth(); HEIGHT = imageTemplate.getHeight(); // 随机生成抠图坐标 generateCutoutCoordinates(); // 最终图像 BufferedImage newImage = new BufferedImage(WIDTH, HEIGHT, imageTemplate.getType()); Graphics2D graphics = newImage.createGraphics(); graphics.setBackground(Color.white); int bold = 5; // 获取感兴趣的目标区域 BufferedImage targetImageNoDeal = getTargetArea(X, Y, WIDTH, HEIGHT, targetIs, targetType); // 根据模板图片抠图 newImage = dealCutPictureByTemplate(targetImageNoDeal, imageTemplate, newImage); // 设置“抗锯齿”的属性 graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setStroke(new BasicStroke(bold, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); graphics.drawImage(newImage, 0, 0, null); graphics.dispose(); //新建流。 ByteArrayOutputStream os = new ByteArrayOutputStream(); //利用ImageIO类提供的write方法,将bi以png图片的数据模式写入流。 ImageIO.write(newImage, "png", os); byte[] newImages = os.toByteArray(); pictureMap.put("newImage", newImages); // 源图生成遮罩 BufferedImage oriImage = ImageIO.read(targetFile); byte[] oriCopyImages = dealOriPictureByTemplate(oriImage, imageTemplate, X, Y); pictureMap.put("oriCopyImage", oriCopyImages); System.out.println("X="+X+";y="+Y); return pictureMap; } /** * 抠图后原图生成 * @param oriImage 原始图片 * @param templateImage 模板图片 * @param x 坐标X * @param y 坐标Y * @return 添加遮罩层后的原始图片 * @throws Exception 异常 */ private static byte[] dealOriPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage, int x, int y) throws Exception { // 源文件备份图像矩阵 支持alpha通道的rgb图像 BufferedImage oriCopyImage = new BufferedImage(oriImage.getWidth(), oriImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); // 源文件图像矩阵 int[][] oriImageData = getData(oriImage); // 模板图像矩阵 int[][] templateImageData = getData(templateImage); //copy 源图做不透明处理 for (int i = 0; i < oriImageData.length; i++) { for (int j = 0; j < oriImageData[0].length; j++) { int rgb = oriImage.getRGB(i, j); int r = (0xff & rgb); int g = (0xff & (rgb >> 8)); int b = (0xff & (rgb >> 16)); //无透明处理 rgb = r + (g 16)); rgb_ori = r + (g


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3